<template>
  <div class="carousel" @mouseenter="stopPlay" @mouseleave="startPlay">
    <ul class="carousel-body">
      <li
        class="carousel-item"
        v-for="(image, index) in bannerImageList"
        :key="image.id"
        :class="{ fade: index === currentIndex }"
      >
        <router-link to="#">
          <img :src="image.imgUrl" alt="" />
        </router-link>
      </li>
    </ul>
    <a href="javascript:;" class="carousel-btn prev" @click="prev">
      <IconifyIcon icon="ooui:previous-ltr" />
    </a>
    <a href="javascript:;" class="carousel-btn next" @click="next">
      <IconifyIcon icon="ooui:previous-rtl" />
    </a>
    <div class="carousel-indicator">
      <span
        v-for="(item, index) in bannerImageList"
        :key="item.id"
        :class="{ active: index === currentIndex }"
      ></span>
    </div>
  </div>
</template>

<script setup lang="ts">
import type { Banner } from '@/api/home/types.d'
import { ref, withDefaults, watch, onBeforeUnmount } from 'vue'
defineOptions({
  name: 'Carousel'
})

interface Props {
  /** 轮播图图片数据 */
  bannerImageList: Banner[]
  /** 自动播放的配置 */
  autoPlay?: {
    /** 是否自动播放 */
    play: boolean
    /** 间隔时长 */
    interval: number
  }
}

/** Props */
const props = withDefaults(defineProps<Props>(), {
  autoPlay: () => ({
    play: true,
    interval: 3000
  })
})

/** 轮播图当前显示的图片索引 */
const currentIndex = ref(0)

/** 自动播放 */
let timer: number | null = null

function autoPlayBanner(): void {
  /** 清楚上一次的定时器 */
  clearInterval(timer as number)
  timer = window.setInterval(() => {
    /** 自增1 */
    currentIndex.value++
    /** 如果当前显示的图片的索引超过了总的轮播图片的数量，复位（从头开始） */
    if (currentIndex.value >= props.bannerImageList.length) {
      currentIndex.value = 0
    }
  }, props.autoPlay.interval)
}

watch(
  () => props.bannerImageList,
  (newVal) => {
    if (props.autoPlay.play && newVal.length) {
      autoPlayBanner()
    }
  },
  { immediate: true }
)

/** 停止播放 */
function stopPlay(): void {
  if (timer) clearInterval(timer)
}
/** 启动播放 */
function startPlay(): void {
  if (props.autoPlay.play && props.bannerImageList.length) {
    autoPlayBanner()
  }
}

/** 上一个 */
function prev(): void {
  currentIndex.value--
  /** 当前索引小于0，跳到最后一张图片（如果当前图片是第一张，点左侧上一个按钮，跳到最后一张图片） */
  if (currentIndex.value < 0) {
    currentIndex.value = props.bannerImageList.length - 1
  }
}
/** 下一个 */
function next(): void {
  currentIndex.value++
  /** 当前索引大于等于当前轮播图总图片数量，复位（如果当前图片是最后一张，点击右侧按钮，跳到第一张图片） */
  if (currentIndex.value >= props.bannerImageList.length) {
    currentIndex.value = 0
  }
}

/** 组件销毁之前清除定时器 */
onBeforeUnmount(() => {
  clearInterval(timer as number)
})
</script>

<style lang="scss" scoped>
.carousel {
  position: relative;
  width: 100%;
  min-width: 300px;
  height: 100%;
  min-height: 150px;

  &-body {
    width: 100%;
    height: 100%;
  }

  &-item {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    opacity: 0;
    transition: opacity 0.5s linear;

    &.fade {
      z-index: 1;
      opacity: 1;
    }

    img {
      width: 100%;
      height: 100%;
    }
  }

  &-indicator {
    position: absolute;
    bottom: 20px;
    left: 50%;
    z-index: 2;
    width: 100%;
    text-align: center;
    transform: translateX(-50%);

    span {
      display: inline-block;
      width: 12px;
      height: 12px;
      background-color: rgba(0, 0, 0, 0.2);
      border-radius: 50%;
      cursor: pointer;

      ~ span {
        margin-left: 12px;
      }

      &.active {
        background-color: $basic-white;
      }
    }
  }

  &-btn {
    position: absolute;
    top: 50%;
    z-index: 2;
    width: 44px;
    height: 44px;
    background-color: rgba(0, 0, 0, 0.2);
    border-radius: 50%;
    opacity: 0;
    transition: opacity 0.5s;
    color: #fff;
    text-align: center;
    transform: translateY(-50%);
    line-height: 44px;

    &.prev {
      left: 20px;
    }

    &.next {
      right: 20px;
    }
  }

  &:hover {
    .carousel-btn {
      opacity: 1;
    }
  }
}
</style>
